<template>
  <div class="container">
    <vm-overlay :show="show"
                v-if="show && hasOverlay"
                v-bind="mergeOverlayCfg"
                :can-auto-close="overlayCanClose"
                @overlayBodyClicking="overlayBodyClicking"
                @overlayBodyClicked="overlayBodyClicked"></vm-overlay>
    <div ref="vm-mask"
         class="vm-mask"
         v-if="show"
         :hack="shouldShow"
         :style="maskStyle"
         @click="maskClicked">
      <div :style="contentStyle">
        <slot></slot>
      </div>
      <div class="mask-bottom"
           :style="{ width: width + 'px' }"
           @click="closeIconClicked"
           v-if="showClose">
        <text aria-label="关闭"
              class="icon mask-close-icon">&#xe844;</text>
      </div>
    </div>
  </div>
</template>

<script>
const animation = weex.requireModule('animation');
import VmOverlay from './vm-overlay';
export default {
  components: { VmOverlay },
  props: {
    height: {
      type: [String, Number],
      default: 800
    },
    width: {
      type: [String, Number],
      default: 702
    },
    top: {
      type: Number,
      default: 0
    },
    show: {
      type: Boolean,
      default: false
    },
    showClose: {
      type: Boolean,
      default: false
    },
    duration: {
      type: [String, Number],
      default: 200
    },
    hasOverlay: {
      type: Boolean,
      default: true
    },
    hasAnimation: {
      type: Boolean,
      default: true
    },
    timingFunction: {
      type: Array,
      default: () => (['ease-out', 'ease-in'])
    },
    overlayCfg: {
      type: Object,
      default: () => ({
        hasAnimation: true,
        timingFunction: ['ease-out', 'ease-in'],
        canAutoClose: true,
        duration: 200,
        opacity: 0.6
      })
    },
    borderRadius: {
      type: [String, Number],
      default: 10
    },
    overlayCanClose: {
      type: Boolean,
      default: true
    },
    maskBgColor: {
      type: String,
      default: '#ffffff'
    },
    maskCanClose: {
      type: Boolean,
      type: false
    }
  },
  data: () => ({
    maskTop: 264,
    opened: false
  }),
  computed: {
    mergeOverlayCfg() {
      return {
        ...this.overlayCfg,
        hasAnimation: this.hasAnimation
      }
    },
    maskStyle() {
      const { width, height, showClose, hasAnimation, opened, top } = this;
      const newHeight = showClose ? height - 0 + 100 : height;
      const { deviceHeight, deviceWidth, platform } = weex.config.env;
      const _deviceHeight = deviceHeight || 1334;
      const isWeb = typeof (window) === 'object' && platform.toLowerCase() === 'web';
      const navHeight = isWeb ? 0 : 130;
      const pageHeight = _deviceHeight / deviceWidth * 750 - navHeight;
      return {
        width: width + 'px',
        height: newHeight + 'px',
        left: (750 - width) / 2 + 'px',
        top: (top || (pageHeight - height) / 2) + 'px',
        opacity: hasAnimation && !opened ? 0 : 1
      }
    },
    contentStyle() {
      return {
        width: this.width + 'px',
        backgroundColor: this.maskBgColor,
        height: this.height + 'px',
        borderRadius: this.borderRadius + 'px'
      }
    },
    shouldShow() {
      const { show, hasAnimation } = this;
      hasAnimation && setTimeout(() => {
        this.appearMask(show);
      }, 10);
      return show;
    }
  },
  methods: {
    maskClicked() {
      if (this.maskCanClose) {
        this.appearMask(false)
      }
      this.$emit('maskClicked', {})
    },
    closeIconClicked() {
      this.appearMask(false)
    },
    overlayBodyClicking() {
      if (this.hasAnimation) {
        this.appearMask(false)
        this.$emit('overlayBodyClicking', {})
      }
    },
    overlayBodyClicked() {
      if (!this.hasAnimation) {
        this.appearMask(false);
        this.$emit('overlayBodyClicked', {})
      }
    },
    hide() {
      this.appearMask(false)
    },
    needEmit(bool = false) {
      this.opened = bool
      if (!bool) {
        this.$emit('update:show', bool)
        this.$emit('close', bool)
      }
    },
    appearMask(bool, duration = this.duration) {
      const { hasAnimation, timingFunction } = this
      const maskEl = this.$refs['vm-mask']
      if (hasAnimation && maskEl) {
        animation.transition(maskEl, {
          styles: {
            opacity: bool ? 1 : 0
          },
          duration,
          timingFunction: timingFunction[bool ? 0 : 1],
          delay: 0
        }, () => {
          this.needEmit(bool)
        });
      } else {
        this.needEmit(bool)
      }
    }
  }
};
</script>

<style scoped>
.icon {
  font-family: alicon;
}
.container {
  position: fixed;
  width: 750px;
  /*兼容H5异常*/
  z-index: 99999;
}
.vm-mask {
  position: fixed;
  top: 300px;
  left: 60px;
  width: 702px;
  height: 800px;
}
.mask-bottom {
  width: 100px;
  height: 100px;
  background-color: transparent;
  justify-content: center;
  align-items: center;
}
.mask-close-icon {
  color: #f0f0f0;
  font-size: 36px;
}
</style>